#include <stdio.h>
#include <fstream>
#include <string>

#define BAD "[7m"
#define OK "[m"

using namespace std;

int test(string& line){
  const char* str = line.c_str();
	int len = line.length();
  
  int bad = 0;
  unsigned char byte;
	for( int i=0; i<len; i++ ){
    byte = str[i];

    if( (byte & 0x80) == 0x00 ){
      printf("%c", byte);      
      continue;
    }
    
    // Possible 2 BYTE UTF8 Character
    if( (byte & 0xE0) == 0xC0 ){
      if( (len-i) >= 2 ){
        unsigned char byte2 = str[++i]; // process the second byte
        if( (byte2 & 0xC0) == 0x80 ){
          printf("<%X %X>", byte, byte2);
        }else{
          printf(BAD);      
          printf("<%X %X>", byte, byte2);
          printf(OK);      
          i--;
          bad++;
        }
      }else{
          printf(BAD);      
          printf("<%X>", byte);
          printf(OK);      
          bad++;
      }
    }

    // Possible 3 Byte UTF8 Character
    if( (byte & 0xF0) == 0xE0 ){
      if( (len-i) >= 3 ){
        unsigned char byte2 = str[++i];  // Process the second byte
        if( (byte2 & 0xC0) == 0x80 ){
          unsigned char byte3 = str[++i];  // Process the second byte
          if( (byte3 & 0xC0) == 0x80 ){
            printf("<%X %X %X>", byte, byte2, byte3);
          }else{
          printf(BAD);      
          printf("<%X %X %X>", byte, byte2, byte3);
          printf(OK);      
            bad++;
            i -= 2;
          }
        }else{
          printf(BAD);      
          printf("<%X %X>", byte, byte2);
          printf(OK);      
          bad++;
          i--;
        }
      }else{
          printf(BAD);      
          printf("<%X>", byte);
          printf(OK);      
        bad++;
      }
      continue;
    }
        
    // Possible 4 Byte UTF-8 Character
    if( (byte & 0xF8) == 0xF0 ){
      if( (len-i) >= 4 ){
        unsigned char byte2 = str[++i];  // Process the second byte
        if( (byte2 & 0xC0) == 0x80 ){
          unsigned char byte3 = str[++i];  // Process the third byte
            if( (byte3 & 0xC0) == 0x80 ){
              unsigned char byte4 = str[++i];  // Process the fourth byte
              if( (byte4 & 0xC0) == 0x80 ){
                 printf("<%X %X %X %X>", byte, byte2, byte3, byte4);
              }else{
                 printf(BAD);
                 printf("<%X %X %X %X>", byte, byte2, byte3, byte4);
                 printf(OK);
                 bad++;
                 i -= 3;
              }
            }else{
              printf(BAD);
              printf("<%X %X %X>", byte, byte2, byte3);
              printf(OK);
              bad++;
              i -= 2;
            }
          }else{
            printf(BAD);
            printf("<%X %X>", byte, byte2);
            printf(OK);
            bad++;
            i--;
          }
        }else{
          printf(BAD);
          printf("<%X>", byte);
          printf(OK);
          bad++;
        }
        continue;
     }
  }
        
  printf("\n");
  return bad;
} 


int main(int argc, char** argv){

  int length;
  unsigned char* buffer;

  ifstream is;
  is.open (argv[argc-1], ios::binary );

  string ln;
	int bad;
  while( !is.eof() ){
	  getline(is, ln);
    bad += test(ln);
  }	
  is.close();

  if( bad > 0 ){
//    cout << "There were " << bad << " bad characters in this file" << endl; 
  }

  return 0;
}
